﻿using System;
using System.IO;
using System.Text;
using System.Linq;
using Newtonsoft.Json;
using System.Reflection;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace CoreShop.Library
{
    /// <summary>
    /// this扩展方法
    /// fmj
    /// </summary>
    public static class ThisTool
    {
        /// <summary>
        /// 实体转Json
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="classObject"></param>
        /// <returns></returns>
        public static string ToJsonString<T>(this T classObject) where T : class
        {
            return JsonConvert.SerializeObject(classObject);
        }

        /// <summary>
        /// Json转实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="classObject"></param>
        /// <returns></returns>
        public static T JsonToEntity<T>(this string classObject) where T : class
        {
            try
            {

                if (string.IsNullOrEmpty(classObject))
                {
                    return default(T);
                }

                return JsonConvert.DeserializeObject<T>(classObject);
            }
            catch (Exception ex)
            {
                //Log.LogManage.Error("json实例化错误:" + ex);
                return null;
            }
        }

        
        /// <summary>
        /// 乘
        /// </summary>
        /// <param name="dec"></param>
        /// <returns></returns>
        public static decimal Mul(this decimal dec, decimal dec1)
        {
            return dec * dec1;
        }


        /// <summary>
        /// 减
        /// </summary>
        /// <param name="dec"></param>
        /// <returns></returns>
        public static decimal Sub(this decimal dec, decimal dec1)
        {
            return dec - dec1;
        }


        /// <summary>
        /// 是否是数字和字母
        /// </summary>
        /// <param name="dec"></param>
        /// <returns></returns>
        public static bool PatternEnglishNumAndLetter(this string dec)
        {
            return Regex.IsMatch(dec, @"^[a-zA-Z0-9]+$");
        }

        /// <summary>
        /// 是否是数字
        /// </summary>
        /// <param name="dec"></param>
        /// <returns></returns>
        public static bool PatternNum(this string dec)
        {
            return (Regex.IsMatch(dec, @"^[0-9]+$") || PatternOnePointForNum(dec));
        }

        /// <summary>
        /// 是否只是数字
        /// </summary>
        /// <param name="dec"></param>
        /// <returns></returns>
        public static bool PatternOnlyNum(this string dec)
        {
            return Regex.IsMatch(dec, @"^[0-9]+$");
        }

        /// <summary>
        /// 是否是字母
        /// </summary>
        /// <param name="dec"></param>
        /// <returns></returns>
        public static bool PatternEnglishLetter(this string dec)
        {
            return Regex.IsMatch(dec, @"^[a-zA-Z]+$");
        }

        /// <summary>
        /// 是否只有一个小数点的数字
        /// </summary>
        /// <param name="dec"></param>
        /// <returns></returns>
        public static bool PatternOnePointForNum(this string dec)
        {
            return Regex.IsMatch(dec, @"^[0-9]+[\.]{1}$") ||
                Regex.IsMatch(dec, @"^[\.]{1}$") ||
                Regex.IsMatch(dec, @"^[0-9]+[\.]{1}[0-9]+$") ||
                Regex.IsMatch(dec, @"^[\.]{1}[0-9]+$") ||
                Regex.IsMatch(dec, @"^\d{1,3}(,\d{3})*(\.\d{0,3})?$");
        }

        /// <summary>
        /// 是否是url
        /// </summary>
        /// <param name="dec"></param>
        /// <returns></returns>
        public static bool PatternUrl(this string dec)
        {
            return Regex.IsMatch(dec, @"^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:\/?#[\]@!\$&'\(\)\*\+,;=.]+$");
        }

        /// <summary>
        /// 验证是否支付宝
        /// </summary>
        /// <param name="dec"></param>
        /// <returns></returns>
        public static bool PatternAlipay(this string dec)
        {
            return Regex.IsMatch(dec, @"^(25|26|27|28|29|30)\d{14,22}$");
        }

        /// <summary>
        /// 验证是否云闪付
        /// </summary>
        /// <param name="dec"></param>
        /// <returns></returns>
        public static bool PatternUnionpay(this string dec)
        {
            return Regex.IsMatch(dec, @"^62\d{17}$");
        }
        
        /// <summary>
        /// 验证是否微信
        /// </summary>
        /// <param name="dec"></param>
        /// <returns></returns>
        public static bool PatternWechat(this string dec)
        {
            return Regex.IsMatch(dec, @"^(10|11|12|13|14|15)\d{16}$");
        }

        /// <summary>
        /// 验证是否付款码
        /// </summary>
        /// <param name="dec"></param>
        /// <returns></returns>
        public static bool PatternPayCode(this string dec)
        {
            return PatternWechat(dec) || PatternAlipay(dec) || PatternUnionpay(dec);
        }

        /// <summary>
        /// 线程回收
        /// </summary>
        /// <param name="action"></param>
        public static void TaskDis(this Task task)
        {
            task.ContinueWith(res =>
            {
                res.Dispose();
            });
        }

        /// <summary>
        /// 流转字节
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static byte[] StreamToByte(this Stream stream)
        {
            stream.Seek(0, SeekOrigin.Begin);
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);

            // 设置当前流的位置为流的开始 
            stream.Seek(0, SeekOrigin.Begin);
            return bytes;
        }

        /// <summary>
        /// 得到对象的弱引用
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static T GetWeakReference<T>(this object obj) where T : class
        {
            return new WeakReference(obj).Target as T;
        }


        /// <summary>
        /// 深拷贝分类
        /// </summary>
        /// <param name="item2s"></param>
        /// <returns></returns>
        public static List<Control> DeepCopyItems4Control(this List<Control> items)
        {
            List<Control> itemsCopy =
                    new List<Control>();
            //深拷贝
            items.ForEach(item2sItem =>
            {
                itemsCopy.Add(item2sItem);
            });

            return itemsCopy;
        }

        /// <summary>
        /// 父对象拷贝到子对象
        /// </summary>
        /// <typeparam name="TParent"></typeparam>
        /// <typeparam name="TChild"></typeparam>
        /// <param name="parent"></param>
        /// <returns></returns>
        public static TChild Copy2Child<TParent, TChild>(this TParent parent) where TChild : TParent, new()
        {
            TChild child = new TChild();
            Type ParentType = typeof(TParent);
            PropertyInfo[] Properties = ParentType.GetProperties();

            foreach (var Propertie in Properties)
            {
                //循环遍历属性
                if (Propertie.CanRead && Propertie.CanWrite)
                {
                    //进行属性拷贝
                    Propertie.SetValue(child, Propertie.GetValue(parent, null), null);
                }
            }

            return child;
        }




        /// <summary>
        /// 对象是否为空
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool Empty(this object obj)
        {
            return obj == null;
        }

        
        /// <summary>
        /// 转为毫秒
        /// </summary>
        /// <param name="dec"></param>
        /// <returns></returns>
        public static int ToMil(this float dec)
        {
            return Int32.Parse((dec * 1000).ToString());
        }

       
        /// <summary>
        /// 键值对排序
        /// </summary>
        /// <param name="keyValues"></param>
        /// <returns></returns>
        public static Dictionary<int, string> SortDic(this Dictionary<int, string> keyValues)
        {
            //排序
            return keyValues.OrderBy(x =>
            {
                return x.Key;
            }).ToDictionary(pair => pair.Key, pair => pair.Value);
        }

        /// <summary>
        /// 四舍五入
        /// </summary>
        /// <param name="dec"></param>
        /// <param name="bit">保留的位数</param>
        /// <returns></returns>
        public static decimal Round(this decimal dec, int bit = 2)
        {
            return Math.Round(dec, bit, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// 检查是否为移动支付方式
        /// </summary>
        /// <param name="strItem"></param>
        /// <returns></returns>
        public static string RetrunMobilePayCodeType(this string strItem)
        {
            if (string.IsNullOrEmpty(strItem))
            {
                return "";
            }
            //微信 18位纯数字，以10、11、12、13、14、15开头
            //支付宝 支付宝的支付码规则是：25~30开头的长度为16~24位的数字
            if (strItem.Length >= 16)
            {
                string strTwoPrefix = strItem.Substring(0, 2);
                if (strTwoPrefix == "10" || strTwoPrefix == "11" || strTwoPrefix == "12" || strTwoPrefix == "13" || strTwoPrefix == "14" || strTwoPrefix == "15")
                {
                    if (strItem.Length == 18)
                    {
                        return "WX";
                    }
                }
                else if (strTwoPrefix == "25" || strTwoPrefix == "26" || strTwoPrefix == "27" || strTwoPrefix == "28" || strTwoPrefix == "29" || strTwoPrefix == "30")
                {
                    if (strItem.Length >= 16 || strItem.Length <= 24)
                    {
                        //支付宝
                        return "ZFB";
                    }
                }
                //云闪付
                else if (strTwoPrefix == "62" || strTwoPrefix == "18" && strItem.Length >= 18 && strItem.Length <= 19)
                {
                    //云闪付
                    return "YSF";
                }
            }
            return "";
        }

        public static string RetrunMobilePayCodeTypeName(this string strItem)
        {
            if (string.IsNullOrEmpty(strItem))
            {
                return "";
            }
            //微信 18位纯数字，以10、11、12、13、14、15开头
            //支付宝 支付宝的支付码规则是：25~30开头的长度为16~24位的数字
            if (strItem == "WX")
            {
                return "微信";
            }
            else if (strItem == "ZFB")
            {
                return "支付宝";
            }
            //云闪付
            else if (strItem == "YSF")
            {
                return "云闪付";
            }
            return "";
        }

        /// <summary>
        /// 校验手机号
        /// </summary>
        /// <param name="strPhone"></param>
        /// <returns></returns>
        public static bool IsValidPhoneNumber(this string strPhone) 
        {
            Regex PhoneRegex = new Regex(@"^1[3-9]\d{9}$");
            return !string.IsNullOrEmpty(strPhone) && PhoneRegex.IsMatch(strPhone);
        }
        
    }
}
